# -*- coding: utf-8 -*-
"""
日志管理模块
提供统一的日志记录和错误处理功能
"""

import logging
import os
import sys
from logging.handlers import RotatingFileHandler
from typing import Optional
from datetime import datetime
import traceback
from functools import wraps


class ColoredFormatter(logging.Formatter):
    """彩色日志格式化器"""
    
    # 颜色代码
    COLORS = {
        'DEBUG': '\033[36m',    # 青色
        'INFO': '\033[32m',     # 绿色
        'WARNING': '\033[33m',  # 黄色
        'ERROR': '\033[31m',    # 红色
        'CRITICAL': '\033[35m', # 紫色
        'RESET': '\033[0m'      # 重置
    }
    
    def format(self, record):
        """格式化日志记录
        
        Args:
            record: 日志记录对象
            
        Returns:
            格式化后的日志字符串
        """
        # 获取颜色
        color = self.COLORS.get(record.levelname, self.COLORS['RESET'])
        reset = self.COLORS['RESET']
        
        # 格式化消息
        record.levelname = f"{color}{record.levelname}{reset}"
        
        return super().format(record)


class LoggerManager:
    """日志管理器"""
    
    def __init__(self, name: str = "chunker", config=None):
        """初始化日志管理器
        
        Args:
            name: 日志器名称
            config: 日志配置对象
        """
        self.name = name
        self.config = config
        self.logger = None
        self._setup_logger()
        
    def _setup_logger(self):
        """设置日志器"""
        self.logger = logging.getLogger(self.name)
        
        # 避免重复添加处理器
        if self.logger.handlers:
            return
            
        # 设置日志级别
        level = getattr(logging, self.config.level if self.config else 'INFO')
        self.logger.setLevel(level)
        
        # 创建格式化器
        formatter = logging.Formatter(
            self.config.format if self.config else 
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        )
        
        # 添加控制台处理器
        if not self.config or self.config.console_output:
            console_handler = logging.StreamHandler(sys.stdout)
            console_handler.setLevel(level)
            
            # 如果是控制台输出，使用彩色格式化器
            if sys.stdout.isatty():  # 检查是否是终端
                colored_formatter = ColoredFormatter(
                    self.config.format if self.config else 
                    '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
                )
                console_handler.setFormatter(colored_formatter)
            else:
                console_handler.setFormatter(formatter)
                
            self.logger.addHandler(console_handler)
        
        # 添加文件处理器
        if self.config and self.config.log_file:
            # 确保日志目录存在
            log_dir = os.path.dirname(self.config.log_file)
            if log_dir:
                os.makedirs(log_dir, exist_ok=True)
                
            # 创建旋转文件处理器
            file_handler = RotatingFileHandler(
                self.config.log_file,
                maxBytes=self.config.max_file_size * 1024 * 1024,  # 转换为字节
                backupCount=self.config.backup_count,
                encoding='utf-8'
            )
            file_handler.setLevel(level)
            file_handler.setFormatter(formatter)
            self.logger.addHandler(file_handler)
            
    def debug(self, message: str, *args, **kwargs):
        """记录调试信息
        
        Args:
            message: 日志消息
            *args: 格式化参数
            **kwargs: 其他参数
        """
        self.logger.debug(message, *args, **kwargs)
        
    def info(self, message: str, *args, **kwargs):
        """记录信息
        
        Args:
            message: 日志消息
            *args: 格式化参数
            **kwargs: 其他参数
        """
        self.logger.info(message, *args, **kwargs)
        
    def warning(self, message: str, *args, **kwargs):
        """记录警告信息
        
        Args:
            message: 日志消息
            *args: 格式化参数
            **kwargs: 其他参数
        """
        self.logger.warning(message, *args, **kwargs)
        
    def error(self, message: str, *args, **kwargs):
        """记录错误信息
        
        Args:
            message: 日志消息
            *args: 格式化参数
            **kwargs: 其他参数
        """
        self.logger.error(message, *args, **kwargs)
        
    def critical(self, message: str, *args, **kwargs):
        """记录严重错误信息
        
        Args:
            message: 日志消息
            *args: 格式化参数
            **kwargs: 其他参数
        """
        self.logger.critical(message, *args, **kwargs)
        
    def exception(self, message: str, *args, **kwargs):
        """记录异常信息（包含堆栈跟踪）
        
        Args:
            message: 日志消息
            *args: 格式化参数
            **kwargs: 其他参数
        """
        self.logger.exception(message, *args, **kwargs)
        
    def log_function_call(self, func_name: str, args: tuple = None, kwargs: dict = None):
        """记录函数调用
        
        Args:
            func_name: 函数名称
            args: 位置参数
            kwargs: 关键字参数
        """
        args_str = f"args={args}" if args else ""
        kwargs_str = f"kwargs={kwargs}" if kwargs else ""
        params = ", ".join(filter(None, [args_str, kwargs_str]))
        
        self.debug(f"调用函数: {func_name}({params})")
        
    def log_performance(self, operation: str, duration: float, details: str = ""):
        """记录性能信息
        
        Args:
            operation: 操作名称
            duration: 执行时间（秒）
            details: 详细信息
        """
        message = f"性能统计 - {operation}: {duration:.3f}秒"
        if details:
            message += f" ({details})"
        self.info(message)
        
    def log_file_operation(self, operation: str, file_path: str, success: bool = True, error: str = ""):
        """记录文件操作
        
        Args:
            operation: 操作类型（读取、写入、删除等）
            file_path: 文件路径
            success: 是否成功
            error: 错误信息
        """
        if success:
            self.info(f"文件{operation}成功: {file_path}")
        else:
            self.error(f"文件{operation}失败: {file_path} - {error}")
            
    def log_user_action(self, action: str, details: str = ""):
        """记录用户操作
        
        Args:
            action: 操作名称
            details: 操作详情
        """
        message = f"用户操作: {action}"
        if details:
            message += f" - {details}"
        self.info(message)
        
    def log_system_info(self, info: dict):
        """记录系统信息
        
        Args:
            info: 系统信息字典
        """
        self.info("系统信息:")
        for key, value in info.items():
            self.info(f"  {key}: {value}")


class ErrorHandler:
    """错误处理器"""
    
    def __init__(self, logger: LoggerManager):
        """初始化错误处理器
        
        Args:
            logger: 日志管理器
        """
        self.logger = logger
        
    def handle_exception(self, exc: Exception, context: str = "") -> str:
        """处理异常
        
        Args:
            exc: 异常对象
            context: 上下文信息
            
        Returns:
            错误消息
        """
        error_msg = f"{type(exc).__name__}: {str(exc)}"
        if context:
            error_msg = f"{context} - {error_msg}"
            
        # 记录异常详情
        self.logger.error(error_msg)
        self.logger.debug(f"异常堆栈:\n{traceback.format_exc()}")
        
        return error_msg
        
    def handle_file_error(self, file_path: str, operation: str, exc: Exception) -> str:
        """处理文件操作错误
        
        Args:
            file_path: 文件路径
            operation: 操作类型
            exc: 异常对象
            
        Returns:
            错误消息
        """
        error_msg = f"文件{operation}失败 [{file_path}]: {str(exc)}"
        self.logger.error(error_msg)
        return error_msg
        
    def handle_validation_error(self, field: str, value: any, reason: str) -> str:
        """处理验证错误
        
        Args:
            field: 字段名
            value: 字段值
            reason: 错误原因
            
        Returns:
            错误消息
        """
        error_msg = f"参数验证失败 [{field}={value}]: {reason}"
        self.logger.warning(error_msg)
        return error_msg
        
    def handle_processing_error(self, item: str, step: str, exc: Exception) -> str:
        """处理处理过程错误
        
        Args:
            item: 处理项目
            step: 处理步骤
            exc: 异常对象
            
        Returns:
            错误消息
        """
        error_msg = f"处理错误 [{item}] 在步骤 [{step}]: {str(exc)}"
        self.logger.error(error_msg)
        return error_msg


def log_execution_time(logger: LoggerManager):
    """装饰器：记录函数执行时间
    
    Args:
        logger: 日志管理器
    """
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            start_time = datetime.now()
            logger.log_function_call(func.__name__, args, kwargs)
            
            try:
                result = func(*args, **kwargs)
                duration = (datetime.now() - start_time).total_seconds()
                logger.log_performance(func.__name__, duration)
                return result
            except Exception as e:
                duration = (datetime.now() - start_time).total_seconds()
                logger.error(f"函数 {func.__name__} 执行失败 (耗时 {duration:.3f}秒): {str(e)}")
                raise
                
        return wrapper
    return decorator


def handle_exceptions(logger: LoggerManager, reraise: bool = True):
    """装饰器：处理函数异常
    
    Args:
        logger: 日志管理器
        reraise: 是否重新抛出异常
    """
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                error_handler = ErrorHandler(logger)
                error_handler.handle_exception(e, f"函数 {func.__name__}")
                
                if reraise:
                    raise
                return None
                
        return wrapper
    return decorator


# 创建默认日志管理器
default_logger = LoggerManager()